package com.wubo.sec.model;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.wubo.sec.acl.AuthAcl;
import com.wubo.sec.acl.core.AclModel;
import com.wubo.sec.acl.core.GlobalAcl;
import com.wubo.sec.config.LangUtil;

/** 权限
 * @author WuBo
 * @CreateDate 2010-7-25
 * @version 1.0.01
 */
@Entity
@Table(name="SEC_AUTH")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Authority implements Serializable, Comparable<Authority>, Cloneable, AclModel {
	private static final long serialVersionUID = 2104413895923604285L;

	public final static String ADMIN = "ADMIN";
	
	public final static Authority DEFAULT_AUTH = new Authority("IS_AUTHENTICATED_FULLY", LangUtil.get("DefaultAuthority"), "SYSTEM", true);
	public final static Authority ANONYM_AUTH = new Authority("IS_AUTHENTICATED_ANONYMOUSLY", LangUtil.get("AnonymAuthority"), "SYSTEM", true);

	@Id
	@Column(unique=true, nullable=true, length=32)
	private String code; //编码，引用键

	@Column(unique=true, nullable=true, length=50)
	private String name; //权限名
	
	private String type; //权限类型
	
	private Date createTime; //创建时间
	private String createUser; //创建用户
	private Date updateTime; //修改时间
	private String updateUser; //修改用户
	
	private String desn; //描述
	
	private boolean locked;
	
	public Authority(){
		
	}
	
	public Authority(String code, String name){
		this.code = code;
		this.name = name;
	}
	
	public Authority(String code, String name, String type, boolean locked){
		this.code = code;
		this.name = name;
		this.type = type;
		this.locked = locked;
	}
	
	@ManyToMany(targetEntity=User.class, 
			mappedBy="userAuthorities", 
			fetch=FetchType.LAZY)
	private Set<User> users; //权限对应用户集合
	
	@ManyToMany(targetEntity=Role.class, 
			mappedBy="authorities", 
			fetch=FetchType.LAZY)
	private Set<Role> roles; //权限对应角色集合 

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getCreateUser() {
		return createUser;
	}

	public void setCreateUser(String createUser) {
		this.createUser = createUser;
	}

	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	public String getUpdateUser() {
		return updateUser;
	}

	public void setUpdateUser(String updateUser) {
		this.updateUser = updateUser;
	}

	public String getDesn() {
		return desn;
	}

	public void setDesn(String desn) {
		this.desn = desn;
	}

	public boolean isLocked() {
		return locked;
	}

	public void setLocked(boolean locked) {
		this.locked = locked;
	}

	public Set<User> getUsers() {
		return users;
	}

	public void setUsers(Set<User> users) {
		this.users = users;
	}

	public Set<Role> getRoles() {
		return roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
	
	public int hashCode(){
		return this.code.hashCode() + 32;
	}
	
	public boolean equals(Object obj){
		if(obj == null) return false;
		if(! (obj instanceof Authority) ){
			return false; 
		}
		
		Authority auth = (Authority) obj;
		return this.getCode().equals(auth.getCode());
	}
	
	public int compareTo(Authority o) {
		if(this.type == null || o.getType() == null){
			return this.getCode().compareTo(o.getCode());
		}
		if(this.getType().equals(o.getType())){
			return this.getCode().compareTo(o.getCode());
		}
		return this.getType().compareTo(o.getType());
	}
	
	public String toString(){
		return "Code:"+code+" Name:"+name+" Type:"+type;
	}
	
	public Authority clone(){
		try{
			return (Authority) super.clone();
		}catch(CloneNotSupportedException e){
			return null;
		}
	}
	
	public GlobalAcl getAcl() {
		return new AuthAcl(this);
	}
}
